package edu.columbia.plt.visage;

import java.awt.Color;
import java.util.*;

import edu.columbia.plt.visage.interfaces.ICell;



/*	Interface Cell 
 * 
 *  By Visage Team
 *  Cell is the container of Agents. An agent will contain in a cell, which have a
 *  list of all agents within this cell.
 *  
 */

public class Cell implements ICell {

	// member variable include:
	private Map<String, Map<Integer, Agent>> agentTypeMap;
	private Color color;

	// construction function
	public Cell() {
		agentTypeMap = new LinkedHashMap<String, Map<Integer, Agent>>();
	}

	// get agents
	/* (non-Javadoc)
	 * @see visage.ICell#getAgentByID(int)
	 */
	public Collection<Agent> getAgentByID(int ID) {
		ArrayList<Agent> agentList = new ArrayList<Agent>();
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			agentList.add(agentMap.get(ID));
		}
		return agentList;
	}

	/* (non-Javadoc)
	 * @see visage.ICell#getAgentsBySize(int)
	 */
	public Collection<Agent> getAgentsBySize(int size) {
		ArrayList<Agent> agentList = new ArrayList<Agent>();
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			for (int id : agentMap.keySet()) {
				Agent agent = agentMap.get(id);
				if (agent.getSize() == size)
					agentList.add(agent);
			}
		}
		return agentList;
	}

	/* (non-Javadoc)
	 * @see visage.ICell#getAgentsByType(java.lang.String)
	 */
	public Collection<Agent> getAgentsByType(String type) {
		ArrayList<Agent> agentList = new ArrayList<Agent>();
		Map<Integer, Agent> agentMap = agentTypeMap.get(type);
		if(agentMap != null){
			agentList.addAll(agentMap.values());
			//System.out.println("ListSize: "+agentList.size());
		}
		return agentList;
	}

	/* (non-Javadoc)
	 * @see visage.ICell#getAgentsByColor(java.awt.Color)
	 */
	public Collection<Agent> getAgentsByColor(Color color) {
		ArrayList<Agent> agentList = new ArrayList<Agent>();
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			for (int id : agentMap.keySet()) {
				Agent agent = agentMap.get(id);
				if (agent.getColor() == color)
					agentList.add(agent);
			}
		}
		return agentList;
	}

	/* (non-Javadoc)
	 * @see visage.ICell#getAllAgents()
	 */
	public Collection<Agent> getAllAgents() {
		ArrayList<Agent> agentList = new ArrayList<Agent>();
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			agentList.addAll(agentMap.values());
		}
		return agentList;
	}

	// remove agents
	/* (non-Javadoc)
	 * @see visage.ICell#removeAgentByID(int)
	 */
	public synchronized void removeAgentByID(int ID) {
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			agentMap.remove(ID);
		}
	}

	/* (non-Javadoc)
	 * @see visage.ICell#removeAgentsBySize(int)
	 */
	public synchronized void removeAgentsBySize(int size) {
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			for (int id : agentMap.keySet()) {
				Agent agent = agentMap.get(id);
				if (agent.getSize() == size)
					agentMap.remove(id);
			}
		}
	}

	/* (non-Javadoc)
	 * @see visage.ICell#removeAgentsByType(java.lang.String)
	 */
	public synchronized void removeAgentsByType(String type) {
		agentTypeMap.remove(type);
	}

	/* (non-Javadoc)
	 * @see visage.ICell#removeAgentsByColor(java.awt.Color)
	 */
	public synchronized void removeAgentsByColor(Color color) {
		for (String agentType : agentTypeMap.keySet()) {
			Map<Integer, Agent> agentMap = agentTypeMap.get(agentType);
			for (int id : agentMap.keySet()) {
				Agent agent = agentMap.get(id);
				if (agent.getColor() == color)
					agentMap.remove(id);
			}
		}
	}

	/* (non-Javadoc)
	 * @see visage.ICell#removeAllAgents()
	 */
	public synchronized void removeAllAgents() {
		agentTypeMap.clear();
	}

	// add an agent
	/* (non-Javadoc)
	 * @see visage.ICell#addAgent(visage.Agent)
	 */
	public synchronized void addAgent(Agent agent) {
		if (!agentTypeMap.containsKey(agent.getType())) {
			agentTypeMap.put(agent.getType(), new LinkedHashMap<Integer, Agent>());
		}
		Map<Integer, Agent> agentMap = agentTypeMap.get(agent.getType());
		agentMap.put(agent.getID(), agent);
	}

	/* (non-Javadoc)
	 * @see visage.ICell#changeColor(java.awt.Color)
	 */
	public void changeColor(Color color) {
		this.color = color;
	}

	/* (non-Javadoc)
	 * @see visage.ICell#getColor()
	 */
	public Color getColor() {
		return color;
	}

}
